﻿Shader "Unlit/MotionBlurV2"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _BlurSize("BlurSize（模糊图像大小）",Float) = 1.0
    }
    SubShader
    {
        CGINCLUDE
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            sampler2D _CameraDepthTexture; //Unity传递的 深度纹理
            float4x4 _CurViewProjInverseMatrix; //脚本传递的 当前的 视角投影矩阵的逆矩阵
            float4x4 _PreViewProjMatrix; //脚本传递的 前一帧的 视角投影矩阵
            half _BlurSize;

            struct a2v
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
            };
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                half2 uv_depth : TEXCOORD1; //采样深度纹理的uv
            };
            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                o.uv_depth = v.texcoord;

                #if UNITY_UV_STARTS_AT_TOP //平台差异处理
                if(_MainTex_TexelSize.y<0)
                    o.uv_depth.y = 1 - o.uv_depth.y;
                #endif

                return o;
            }
            //运动模糊
            fixed4 frag(v2f i) : SV_Target
            {
                //获取深度值（由NDC映射而来）
                float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
                //构建NDC坐标H
                float4 H = float4(i.uv.x*2-1 , i.uv.y*2-1 , d*2-1 , 1);
                //获取世界坐标
                float4 D = mul(_CurViewProjInverseMatrix,H);
                float4 worldPos = D/D.w;

                float4 curPos = H; //当前帧坐标
                float4 prePos = mul(_PreViewProjMatrix,worldPos); //前一帧坐标
                prePos /= prePos.w;

                float2 velocity = (curPos.xy - prePos.xy)/2.0f; //速度 = 过去-> 当前

                float2 uv = i.uv;
                float4 col = tex2D(_MainTex,uv);

                uv += velocity * _BlurSize; //uv沿速度方向移动

                for(int k = 1;k < 3;k++) //三次采样取均值
                {
                    col += tex2D(_MainTex,uv);
                    uv += velocity * _BlurSize;
                }
                col /= 3;
                return fixed4(col.rgb,1);
            } 

        ENDCG

        ZTest Always Cull Off ZWrite Off
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
        }
    } 
    Fallback Off
}
